<?php
/**
 * Created by PhpStorm.
 * User: ysw
 * Date: 2020/6/29
 * Time: 10:37
 */

namespace app\api\service;

use app\api\model\CreateVoteDescribeModel;
use app\api\model\CreateVoteModel;
use app\api\model\UserVoteModel;
use app\api\model\UserModel;
use app\api\model\UserVoteShareModel;
use think\Db;

class CreateVoteService
{
    /**
     * 添加投票
     * @param $data
     * @return bool
     */
    public function addCreateVote($data, $getUserinfo)
    {

        Db::startTrans();
        try {

            $create_vote_describe = $data['create_vote_describe'];
            $deadline = strtotime($data['deadline']);
            if (count($create_vote_describe) < 2) {
                throw new \Exception('至少填写两个选项！');
            }
            if (count($create_vote_describe) > 20) {
                throw new \Exception('最多填写二十个选项！');
            }
            if ($deadline < time()) {
                throw new \Exception('截止日期最晚不能晚于当前时间！');
            }
            if ($data['vote_open'] == 0) {
                if ((int)$data['ad_limit'] !== 0) {
                    throw new \Exception('广告关闭广告上限参数有误！');
                }
                if ((int)$data['ad_last_num'] !== 0) {
                    throw new \Exception('广告关闭完播票数参数有误！');
                }
            } else {
                if ($data['ad_limit'] == 0) {
                    throw new \Exception('广告开启广告上限参数有误！');
                }
                if ($data['ad_last_num'] == 0) {
                    throw new \Exception('广告开启完播票数参数有误！');
                }
            }

            $arr = array(
                'user_id' => $getUserinfo['id'],
                'title' => $data['title'],
                'deadline' => $deadline,
                'vote_num' => $data['vote_num'],
                'vote_open' => $data['vote_open'],
                'ad_limit' => $data['ad_limit'],
                'share_title' => $data['title'],
                'ad_last_num' => $data['ad_last_num'],
                'create_time' => time(),
                'update_time' => time(),
            );
            $id = CreateVoteModel::getInstance()->insertGetId($arr);
            if ($id == 0) {
                throw new \Exception('添加投票失败！');
            }
            $create_vote_describe_arr = [];
            foreach ($create_vote_describe as $k => $v) {
                if (!isset($v['describe']) || empty($v['describe'])) {
                    throw new \Exception('选项文字不能为空！');
                }
                $describe_strlen = mb_strlen($v['describe'],'utf-8');
                if ($describe_strlen < 1 || $describe_strlen > 20) {
                    throw new \Exception('选项文字（1-20个字符）之间！');
                }
                if (!empty($v['img']) && isset($v['img'])) {
                    $create_vote_describe_arr[$k]['img'] = $v['img'];
                }else{
                    $create_vote_describe_arr[$k]['img'] = '';
                }
                $create_vote_describe_arr[$k]['describe'] = $v['describe'];
                $create_vote_describe_arr[$k]['crate_vote_id'] = $id;
                $create_vote_describe_arr[$k]['create_time'] = time();
                $create_vote_describe_arr[$k]['update_time'] = time();
            }


            $create_vote_describe_res = CreateVoteDescribeModel::getInstance()->insertAll($create_vote_describe_arr);
            if (!$create_vote_describe_res) {
                throw new \Exception('添加投票选项失败！');
            }

            Db::commit();
        } catch (\PDOException $e) {
            Db::rollback();
            return ['code' => 0, 'msg' => $e->getMessage()];
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 0, 'msg' => $e->getMessage()];
        }
        return ['code' => 1, 'msg' => '投票成功', 'data' => $id];
    }

    /**
     * 投票列表
     * @param $getUserinfo
     * @param $create_vote_id
     * @return array|false|\PDOStatement|string|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function createVoteList($getUserinfo, $create_vote_id)
    {
        $user_id = $getUserinfo['id'];

        //投票标题
        $create_vote = CreateVoteModel::getInstance()->field('id,title,share_title,deadline,vote_open,vote_num,ad_limit,share_address,user_id,ad_last_num')->where(array('id' => $create_vote_id))->find();
        if (empty($create_vote)){
            return ['code'=>0,'msg'=>'投票不存在'];
        }
        //查询发起投票人的信息
        $user = UserModel::getInstance()->field('id,nickname,avatar')->where(array('id' => $create_vote['user_id']))->find();

        //只有自己发起的投票才会显示拍摄分享
        if ($user_id == $create_vote['user_id']) {
            $share_video = 1;//显示
        } else {
            $share_video = 0;
        }
        //投票选项，图片，描述
        $create_vote_describe = CreateVoteDescribeModel::getInstance()->field('id,crate_vote_id,img,describe')->where(array('crate_vote_id' => $create_vote_id))->select()->toArray();
        $create_vote_describe_arr = array_column($create_vote_describe, 'id');
        //总投票数
        $vote_sum = UserVoteModel::getInstance()->where(array('create_vote_describe_id' => array('in', $create_vote_describe_arr)))->sum('vote_number');

        //投票状态
        if ($create_vote['deadline'] > time()) {
            //用户分享昵称头像
            $user_vote_share = UserVoteShareModel::getInstance()
                ->alias('uvs')
                ->field('u.nickname,u.avatar')
                ->join('user u', 'u.id=uvs.user_id', 'left')
                ->where(array('uvs.create_vote_describe_id' => array('in', $create_vote_describe_arr)))
                ->select()->toArray();//用户分享列表
            $user_vote_share_count = count($user_vote_share);//用户分享数

            //这个用户的投票数(普通投票)
            $user_vote_sum = UserVoteModel::getInstance()->where(array('type'=>0,'user_id' => $user_id, 'create_vote_describe_id' => array('in', $create_vote_describe_arr)))->sum('vote_number');
            //用户广告投票
            $user_vote_sum_video = UserVoteModel::getInstance()->where(array('type'=>1,'user_id' => $user_id, 'create_vote_describe_id' => array('in', $create_vote_describe_arr)))->count();

            //规则
            $remnant_vote = $create_vote['vote_num'] - $user_vote_sum;
            $remnant_vote = $remnant_vote<0 ? 0:$remnant_vote;
            if ($create_vote['vote_open'] == 0) {
                $rule = '每人' . $create_vote['vote_num'] . '票,您还剩' . $remnant_vote . '票';
                $vote_video_count = 0;
            } else {
                $vote_video_count = $create_vote['ad_limit']-$user_vote_sum_video;//用户拍视频的次数
                if($vote_video_count<=0){
                    $rule = '每人' . $create_vote['vote_num'] . '票,您还剩' . $remnant_vote . '票,观看广告次数已用完';
                }else{
                    $rule = '每人' . $create_vote['vote_num'] . '票,您还剩' . $remnant_vote . '票,观看广告可继续投票';
                }
            }

            //用户已投票数
            foreach ($create_vote_describe as $k => &$v) {

                $user_vote_use_total = UserVoteModel::getInstance()->where(array('create_vote_describe_id' => $v['id']))->sum('vote_number');

                $user_vote_use = UserVoteModel::getInstance()->where(array('user_id' => $user_id, 'create_vote_describe_id' => $v['id']))->sum('vote_number');

                $v['user_vote_use_total'] = $user_vote_use_total;//单个选项的总投票数

                $v['user_vote_use'] = $user_vote_use;//这个用户得票数

                if ($vote_sum == 0) {
                    $v['vote_proportion'] = '0.0%';
                } else {
                    $v['vote_proportion'] = number_format($user_vote_use_total / $vote_sum, 3) * 100 . '%';//得票比例
                }
            }

            $data = array(
                'id' => $create_vote['id'],
                'share_title' => $create_vote['share_title'],
                'vote_progress' => 0,//投票进行中
                'nickname' => $user['nickname'],
                'avatar' => $user['avatar'],
                'share_video' => $share_video,
                'share_address' => $create_vote['share_address'],
                'title' => $create_vote['title'],
                'deadline' => date('Y年m月d日', $create_vote['deadline']),
                'rule' => $rule,
                'remnant_vote' => $remnant_vote,//用户还剩多少票
                'vote_open' => $create_vote['vote_open'],//广告是否开启1=开启，0=关闭
                'vote_video_count'=>$vote_video_count,//广告还剩多少次
                'ad_last_num' => $create_vote['ad_last_num'],//广告完播票数
                'vote_sum' => $vote_sum,//总票数
                'create_vote_describe' => $create_vote_describe,
                'user_vote_share_count' => $user_vote_share_count,
                'user_vote_share' => $user_vote_share,
            );
            return ['code'=>1,'msg'=>'获取数据成功','data'=>$data];
        } else {
            $data = array(
                'id'=>$create_vote['id'],
                'share_title' => $create_vote['share_title'],
                'vote_progress' => 1,//投票过期
                'nickname' => $user['nickname'],
                'avatar' => $user['avatar'],
                'title' => $create_vote['title'],
            );
            if (!empty($create_vote_describe)){
                //用户已投票数
                foreach ($create_vote_describe as $k => &$v) {

                    $user_vote_use_total = UserVoteModel::getInstance()->where(array('create_vote_describe_id' => $v['id']))->sum('vote_number');

                    $v['user_vote_use_total'] = $user_vote_use_total;//单个选项的总投票数

                    if ($vote_sum == 0) {
                        $v['vote_proportion'] = '0.0%';
                    } else {
                        $v['vote_proportion'] = number_format($user_vote_use_total / $vote_sum, 3) * 100 . '%';//得票比例
                    }
                }

                $sort = my_sort($create_vote_describe, 'user_vote_use_total', SORT_DESC);
                $data['create_vote_describe'] = $sort;
                return ['code'=>1,'msg'=>'投票已截止','data'=>$data];
            }else{
                $data['create_vote_describe'] = [];
                return ['code'=>1,'msg'=>'投票已截止','data'=>$data];
            }
        }
    }

    /**
     * 用户投票
     * @param $getUserinfo
     * @param $post
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function addUserVote($getUserinfo, $post)
    {
        $user_id = $getUserinfo['id'];
        $create_vote_describe_id = $post['create_vote_describe_id'];
        $create_vote_id = $post['create_vote_id'];
        try {
            //查找投票可用次数
            $create_vote = CreateVoteModel::getInstance()->field('vote_num,deadline')->where(array('id' => $create_vote_id))->find();
            $create_vote_describe = CreateVoteDescribeModel::getInstance()->field('id')->where(array('crate_vote_id' => $create_vote_id))->select()->toArray();
            $create_vote_describe_arr = array_column($create_vote_describe, 'id');
            //查找用户在这几个投票选项中的总投票数
            $user_vote_sum = UserVoteModel::getInstance()->where(array('user_id' => $user_id, 'create_vote_describe_id' => array('in', $create_vote_describe_arr)))->sum('vote_number');
            if ($create_vote['deadline'] < time()) {
                throw new \Exception('投票已截止了！');
            }
            if ($create_vote['vote_num'] <= $user_vote_sum) {
                throw new \Exception('投票次数已用完！');
            }
            $data = array(
                'create_vote_describe_id' => $create_vote_describe_id,
                'user_id' => $user_id,
                'vote_number' => 1,
            );
            $user_save_vote = UserVoteModel::getInstance()->allowField(true)->isUpdate(false)->save($data);
            if (!$user_save_vote) {
                throw new \Exception('投票失败！');
            }
        } catch (\PDOException $e) {
            return ['code' => 0, 'msg' => $e->getMessage()];
        } catch (\Exception $e) {
            return ['code' => 0, 'msg' => $e->getMessage()];
        }
        return ['code' => 1, 'msg' => '投票成功'];
    }

    /**
     * 热门推荐
     * @return array|bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function hotVoteList($count)
    {
        $create_vote_last_today = CreateVoteModel::getInstance()->field('id,title,vote_num,user_id')->whereTime('create_time', 'week')->select()->toArray();
        $res_week = $this->common($create_vote_last_today, $count, $count);

        if ($res_week['code'] !== 0) {
            return ['code' => 1, 'data' => $res_week['data']];
        }
        $create_vote_last_today = CreateVoteModel::getInstance()->field('id,title,vote_num,user_id')->select()->toArray();
        $res = $this->common($create_vote_last_today, 0, $count);
        if ($res['code'] !== 0) {
            return ['code' => 1, 'data' => $res['data']];
        }
        return ['code' => 0];
    }

    /**
     * 今日推荐
     * @param $getUserinfo
     * @param $count
     * @return array|bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function hotVoteListToday($count)
    {
        $create_vote_last_today = CreateVoteModel::getInstance()->field('id,title,vote_num,user_id')->whereTime('create_time', 'today')->select()->toArray();
        $res_today = $this->common($create_vote_last_today, $count, $count);
        if ($res_today['code'] !== 0) {
            return ['code' => 1, 'data' => $res_today['data']];
        }
        $create_vote_last_today = CreateVoteModel::getInstance()->field('id,title,vote_num,user_id')->whereTime('create_time', 'week')->select()->toArray();
        $res_week = $this->common($create_vote_last_today, $count, $count);
        if ($res_week['code'] !== 0) {
            return ['code' => 1, 'data' => $res_week['data']];
        }
        $create_vote_last_today = CreateVoteModel::getInstance()->field('id,title,vote_num,user_id')->select()->toArray();
        $res = $this->common($create_vote_last_today, 0, $count);
        if ($res['code'] !== 0) {
            return ['code' => 1, 'data' => $res['data']];
        }
        return ['code' => 0];
    }

    /**
     * 公共获取投票列表
     * @param $create_vote_last_today
     * @param $count
     * @return array|bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function common($create_vote_last_today, $count, $count_one)
    {
        if (empty($create_vote_last_today)){
            return ['code' => 0];
        }
        if (count($create_vote_last_today) >= $count) {
            foreach ($create_vote_last_today as $k => &$v) {
                $create_vote_describe = CreateVoteDescribeModel::getInstance()->field('id')->where(array('crate_vote_id' => $v['id']))->select()->toArray();
                $create_vote_describe_arr = array_column($create_vote_describe, 'id');
                $user_vote_sum = UserVoteModel::getInstance()
                    ->where(array('create_vote_describe_id' => array('in', $create_vote_describe_arr)))
                    ->sum('vote_number');
                $v['user_vote_sum'] = $user_vote_sum;
                $v['user_vote_sum_text'] = '用户可以投' . $v['vote_num'] . '票';
                $user = UserModel::getInstance()->field('avatar')->where(array('id'=>$v['user_id']))->find();
                $v['avatar'] = $user['avatar'];
            }

            $sort = my_sort($create_vote_last_today, 'user_vote_sum', SORT_DESC);
            $arr = [];

            for ($i = 0; $i < $count_one; $i++) {
                if (!empty($sort[$i])) {
                    $arr[] = $sort[$i];
                }

            }
            return ['code' => 1, 'data' => $arr];
        }
        return ['code' => 0];
    }

    /**
     * 分享回调
     * @param $getUserinfo
     * @param $post
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function shareNotify($getUserinfo, $post)
    {
        $res_create_vote_descript = $this->selectVote($post);
        if ($res_create_vote_descript['user_id'] == $getUserinfo['id']) {
            //这个用发起的投票，拍摄的抖音链接更新
            CreateVoteModel::getInstance()->where(array('id' => $res_create_vote_descript['id']))->setField('share_address', $post['share_address']);
            return ['code' => 1, 'msg' => '视频分享链接已更新','data'=>$post];
        }else{
            $res_create_vote_descript_id = CreateVoteDescribeModel::getInstance()->field('id')->where(array('crate_vote_id'=>$res_create_vote_descript['id']))->select()->toArray();
            $userVote = UserVoteShareModel::getInstance()->where(array('create_vote_describe_id'=>array('in',array_column($res_create_vote_descript_id,'id')),'user_id'=>$getUserinfo['id']))->find();
            if (empty($userVote)){
                $arr = array(
                    'user_id' => $getUserinfo['id'],
                    'create_vote_describe_id' => $post['create_vote_describe_id'],
                    'share_address' => $post['share_address'],
                );
                UserVoteShareModel::getInstance()->isUpdate(false)->save($arr);
            }else{
                UserVoteShareModel::getInstance()->isUpdate(true)->save(['share_address'=>$post['share_address']],['id'=>$userVote['id']]);
            }
            return ['code' => 1, 'msg' => '视频分享成功','data'=>$post];
        }
    }

    /**
     * 看完广告回调
     * @param $getUserinfo
     * @param $post
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function videoNotify($getUserinfo,$post){
        $res_create_vote_descript = $this->selectVote($post);
        Db::startTrans();
        try {
            //是否开启广告投票
            if ($res_create_vote_descript['vote_open'] == 0) {
                throw new \Exception('该投票暂未开启广告投票！');
            }
            //次数是否用完
            $res_create_vote_descript_id = CreateVoteDescribeModel::getInstance()->field('id')->where(array('crate_vote_id'=>$res_create_vote_descript['id']))->select()->toArray();
            $res_create_vote_descript_count = UserVoteModel::getInstance()->where(array('type'=>1,'user_id'=>$getUserinfo['id'],'create_vote_describe_id'=>array('in',array_column($res_create_vote_descript_id,'id'))))->count();

            if ($res_create_vote_descript_count>=$res_create_vote_descript['ad_limit']){
                throw new \Exception('该广告投票次数已用完！');
            }
            $user_vote = array(
                'create_vote_describe_id'=> $post['create_vote_describe_id'],
                'user_id' => $getUserinfo['id'],
                'vote_number' => $res_create_vote_descript['ad_last_num'],
                'type' =>1
            );
            UserVoteModel::getInstance()->isUpdate(false)->save($user_vote);

            Db::commit();
        } catch (\PDOException $e) {
            Db::rollback();
            return ['code' => 0, 'msg' => $e->getMessage()];
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 0, 'msg' => $e->getMessage()];
        }
        return ['code' => 1, 'msg' => '广告回调成功'];
    }

    /**
     * 删除投票
     * @param $getUserinfo
     * @param $post
     */
    public function myDelVote($getUserinfo,$post){

        $create_vote = CreateVoteModel::getInstance()->field('id,title,deadline,vote_open,vote_num,ad_limit,share_address,user_id')->where(array('user_id'=>$getUserinfo['id'],'id' => $post['create_vote_id']))->find();

        if (empty($create_vote)){
            return ['code' => 0, 'msg' => '没有这个投票记录'];
        }

        $res_create_vote_descript_id = CreateVoteDescribeModel::getInstance()->field('id')->where(array('crate_vote_id'=>$post['create_vote_id']))->select()->toArray();

        $use_vote_count = UserVoteModel::getInstance()->where(array('create_vote_describe_id'=>array('in',array_column($res_create_vote_descript_id,'id'))))->count();

        //投票未结束但还没有人投票的时候可删除.
        if ($create_vote['deadline']>time()){
            if ($use_vote_count>1){
                return ['code' => 0, 'msg' => '有人投票不能删除'];
            }
        }
        Db::startTrans();
        try {
            //删除投票
            CreateVoteModel::getInstance()->where(array('id' => $post['create_vote_id']))->delete();
            //删除投票选项
            CreateVoteDescribeModel::getInstance()->where(array('crate_vote_id'=>$post['create_vote_id']))->delete();
            //删除用户投票
            UserVoteModel::getInstance()->where(array('create_vote_describe_id'=>array('in',array_column($res_create_vote_descript_id,'id'))))->delete();
            //删除用户分享
            UserVoteShareModel::getInstance()->where(array('create_vote_describe_id'=>array('in',array_column($res_create_vote_descript_id,'id'))))->delete();
            Db::commit();
        } catch (\PDOException $e) {
            Db::rollback();
            return ['code' => 0, 'msg' => $e->getMessage()];
        } catch (\Exception $e) {
            Db::rollback();
            return ['code' => 0, 'msg' => $e->getMessage()];
        }
        return ['code' => 1, 'msg' => '删除投票成功'];
    }

    /**
     * 查询单个选项 主投票id
     * @param $post
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function selectVote($post){
        $res_create_vote_descript = CreateVoteDescribeModel::getInstance()
            ->alias('cvd')
            ->field('cv.user_id,cv.id,cv.ad_last_num,cv.ad_limit,cv.vote_open')
            ->join('create_vote cv', 'cv.id=cvd.crate_vote_id', 'left')
            ->where(array('cvd.id' => $post['create_vote_describe_id']))
            ->find();
        return $res_create_vote_descript;
    }
}